package svgedit.svg;

import java.awt.Shape;
import java.awt.geom.Line2D;

import svgedit.gui.Marker;
import svgedit.gui.Marker.MarkerType;

/**
 * Element describing a line segment.
 * 
 * Implements {@literal 9.8.4 Interface SVGLineElement}.
 */
public class SVGLineElement extends SVGStylableElement implements SVGDrawable
{

	private SVGLength x1;
	private SVGLength y1;
	private SVGLength x2;
	private SVGLength y2;

	public SVGLineElement(SVGDocument document)
	{
		super(document);

		x1 = new SVGLength(document, SVGLength.SVG_DIMENSION_X);
		y1 = new SVGLength(document, SVGLength.SVG_DIMENSION_Y);
		x2 = new SVGLength(document, SVGLength.SVG_DIMENSION_X);
		y2 = new SVGLength(document, SVGLength.SVG_DIMENSION_Y);
	}

	@Override
	public void acceptVisitor(SVGVisitor visitor)
	{
		visitor.visitLine(this);
	}

	@Override
	public Shape createShape()
	{
		return new Line2D.Double(x1.getValue(), y1.getValue(), x2.getValue(),
				y2.getValue());
	}

	@Override
	public Shape getSelectionStroke()
	{
		Shape strokedShape = super.getSelectionStroke();

		// Determine which side of selection rect to place marker
		if (this.getX1().getValue() > this.getBounds().getX())
		{
			this.addMarker(strokedShape, this.getBounds().getMaxX(), this
					.getBounds().getY(), MarkerType.LINE_END1); // top-right
		}
		else
		{
			this.addMarker(strokedShape, this.getBounds().getX(), this
					.getBounds().getY(), MarkerType.LINE_END1); // top-left
		}

		// mark centre
		this.addMarker(strokedShape, this.getBounds().getCenterX(), this
				.getBounds().getCenterY(), MarkerType.MOVE);

		// Determine which side of selection rect to place marker
		if (this.getX2().getValue() > this.getBounds().getX())
		{
			this.addMarker(strokedShape, this.getBounds().getMaxX(), this
					.getBounds().getMaxY(), MarkerType.LINE_END1); // bottom-right
		}
		else
		{
			this.addMarker(strokedShape, this.getBounds().getX(), this
					.getBounds().getMaxY(), MarkerType.LINE_END2); // bottom-left
		}

		return strokedShape;

	}

	/**
	 * Gets the first X coordinate
	 * 
	 * @return the first X coordinate
	 */
	public SVGLength getX1()
	{
		return x1;
	}

	/**
	 * Gets the second X coordinate
	 * 
	 * @return the second X coordinate
	 */
	public SVGLength getX2()
	{
		return x2;
	}

	/**
	 * Gets the first Y coordinate
	 * 
	 * @return the first Y coordinate
	 */
	public SVGLength getY1()
	{
		return y1;
	}

	/**
	 * Gets the second Y coordinate
	 * 
	 * @return the second Y coordinate
	 */
	public SVGLength getY2()
	{
		return y2;
	}

	@Override
	public void write(int indent)
	{
		System.out.printf("%" + indent + "s", " ");
		System.out.printf("<line id='%s'>\n", this.toString());

	}

	@Override
	public void drag(double deltaX, double deltaY, Marker.MarkerType mType)
	{
		SVGLineElement line = (SVGLineElement) this;
		switch (mType)
		{
			case MOVE:

				line.getX1().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getX1().getValue() - deltaX)));

				line.getY1().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getY1().getValue() - deltaY)));

				line.getX2().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getX2().getValue() - deltaX)));

				line.getY2().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getY2().getValue() - deltaY)));

				break;
			case LINE_END1:

				line.getX1().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getX1().getValue() - deltaX)));

				line.getY1().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getY1().getValue() - deltaY)));

				break;

			case LINE_END2:

				line.getX2().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getX2().getValue() - deltaX)));

				line.getY2().setValueFromLength(
						new SVGLength(SVGLength.SVG_LENGTHTYPE_PX,
								(float) (line.getY2().getValue() - deltaY)));

				break;
			default:
				assert true;
		}
		// TODO update the marker positions

	}

}
